package cn.iocoder.yudao.module.student.controller.app.student;

import cn.hutool.core.io.IoUtil;
import cn.hutool.json.JSONObject;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.md5.EncryptionUtils;
import cn.iocoder.yudao.framework.common.util.md5.Md5Util;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.infra.api.file.FileApi;
import cn.iocoder.yudao.module.student.controller.app.student.vo.*;
import cn.iocoder.yudao.module.student.convert.student.WebStudentConvert;
import cn.iocoder.yudao.module.student.dal.dataobject.student.WebStudentDO;
import cn.iocoder.yudao.module.student.service.student.WebStudentService;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;

@Api(tags = "管理后台 -学生端- 学生管理")
@RestController
@RequestMapping("/student/web-student")
@Validated
@Slf4j
public class WebStudentController {

    @Resource
    private WebStudentService webStudentService;
    @Resource
    private FileApi fileApi;

    @Value("${yudao.occupation-star.secretId}")
    private String secretId;
    @Value("${yudao.occupation-star.secretKey}")
    private String secretKey;

    @GetMapping("/getWechatOpenId")
    @ApiOperation("获取微信小程序openid")
    public CommonResult<String> getWechatOpenId(@RequestParam(name = "code") String code) throws Exception {
        log.info("code" + code);
        String url = "https://api.weixin.qq.com/sns/jscode2session";
        url += "?appid=wxa1b7157da4197ce2";//自己的appid
        url += "&secret=60abc4dab6d22ae1a6873cb9f988e1a4";//自己的appSecret
        url += "&js_code=" + code;
        url += "&grant_type=authorization_code";
        url += "&connect_redirect=1";
        String res ;
        CloseableHttpResponse response = null;
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        String openid="";
        try {
            HttpGet httpget = new HttpGet(url);    //GET方式
            // 配置信息
            RequestConfig requestConfig = RequestConfig.custom()          // 设置连接超时时间(单位毫秒)
                    .setConnectTimeout(5000)                    // 设置请求超时时间(单位毫秒)
                    .setConnectionRequestTimeout(5000)             // socket读写超时时间(单位毫秒)
                    .setSocketTimeout(5000)                    // 设置是否允许重定向(默认为true)
                    .setRedirectsEnabled(false).build();           // 将上面的配置信息 运用到这个Get请求里
            httpget.setConfig(requestConfig);                         // 由客户端执行(发送)Get请求
            response = httpClient.execute(httpget);                   // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            log.info("响应状态为:" + response.getStatusLine());
            if (responseEntity != null) {
                res = EntityUtils.toString(responseEntity);
                log.info("响应内容为:" + res);
                JSONObject jo =   JsonUtils.parseObject(res,JSONObject.class);
                openid = jo.getStr("openid");
                log.info("openid" + openid);
            }
        }catch (Exception e){
            return error("获取小程序OPENID异常");
        }finally {
            // 释放资源
            if (httpClient != null) {
                httpClient.close();
            }
            if (response != null) {
                response.close();
            }
        }
        return success(openid);
    }

    @PostMapping("/create")
    @ApiOperation("创建学生管理")
    public CommonResult<Long> createWebStudent(@Valid @RequestBody WebStudentCreateReqVO createReqVO) {
        if(null==createReqVO.getStudentAbroad()){
            createReqVO.setStudentAbroad(1);
        }
        return success(webStudentService.createWebStudent(createReqVO));
    }

    @PutMapping("/update")
    @ApiOperation("更新学生管理")
    public CommonResult<Boolean> updateWebStudent(@Valid @RequestBody WebStudentUpdateReqVO updateReqVO) {
        if(null==updateReqVO.getStudentAbroad()){
            updateReqVO.setStudentAbroad(1);
        }
        webStudentService.updateWebStudent(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @ApiOperation("删除学生管理")
    public CommonResult<Boolean> deleteWebStudent(@RequestParam("id") Long id) {
        webStudentService.deleteWebStudent(id);
        return success(true);
    }

    @GetMapping("/get")
    @ApiOperation("获得学生管理")
    public CommonResult<WebStudentRespVO> getWebStudent(@RequestParam("id") Long id) {
        WebStudentDO webStudent = webStudentService.getWebStudent(id);
        return success(WebStudentConvert.INSTANCE.convert(webStudent));
    }

    @GetMapping("/getByMobile")
    @ApiOperation("获得学生管理")
    public CommonResult<WebStudentRespVO> getByMobile(@RequestParam("mobile") String mobile) {
        WebStudentDO webStudent = webStudentService.getWebStudent(mobile);
        return success(WebStudentConvert.INSTANCE.convert(webStudent));
    }

    @GetMapping("/list")
    @ApiOperation("获得学生管理列表")
    public CommonResult<List<WebStudentRespVO>> getWebStudentList(@RequestParam("ids") Collection<Long> ids) {
        List<WebStudentDO> list = webStudentService.getWebStudentList(ids);
        return success(WebStudentConvert.INSTANCE.convertList(list));
    }

    @GetMapping("/page")
    @ApiOperation("获得学生管理分页")
    public CommonResult<PageResult<WebStudentRespVO>> getWebStudentPage(@Valid WebStudentPageReqVO pageVO) {
        PageResult<WebStudentDO> pageResult = webStudentService.getWebStudentPage(pageVO);
        PageResult<WebStudentRespVO> page = WebStudentConvert.INSTANCE.convertPage(pageResult);
        if(page.getTotal()>0){
            List<WebStudentRespVO> list = page.getList();
            list.stream().forEach(m->{
                String cardNo=m.getCardNo();
                if(StringUtils.isNotBlank(cardNo)){
                    m.setCardNo(cardNo.substring(0,4)+"****"+cardNo.substring(14));
                }
                m.setAuthenticationBackPictureUrl("");
                m.setAuthenticationFrontPictureUrl("");
                m.setAuthenticationCardBackPictureUrl("");
                m.setAuthenticationCardFrontPictureUrl("");
                if(StringUtils.isNotBlank(m.getMobile())){
                    m.setMobile(m.getMobile().substring(0,3)+"****"+m.getMobile().substring(8));
                }
            });
        }
        return success(page);
    }

    @GetMapping("/export-excel")
    @ApiOperation("导出学生管理 Excel")
    @OperateLog(type = EXPORT)
    public void exportWebStudentExcel(@Valid WebStudentExportReqVO exportReqVO,
              HttpServletResponse response) throws IOException {
        List<WebStudentDO> list = webStudentService.getWebStudentList(exportReqVO);
        // 导出 Excel
        List<WebStudentExcelVO> datas = WebStudentConvert.INSTANCE.convertList02(list);
        ExcelUtils.write(response, "学生管理.xls", "数据", WebStudentExcelVO.class, datas);
    }


    @PostMapping("/askAuthorized")
    @ApiOperation("创建学生管理")
    public CommonResult<Long> askAuthorized(@Valid @RequestBody WebStudentCreateReqVO createReqVO) {
        createReqVO.setStatus("3");
        return success(webStudentService.createWebStudent(createReqVO));
    }

    @PostMapping("/upload")
    @ApiOperation("上传文件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "文件附件", required = true, dataTypeClass = MultipartFile.class)
    })
    public CommonResult<String> uploadFile(@RequestParam("file") MultipartFile file) throws Exception {
        String originName = file.getOriginalFilename();
        if(StringUtils.isEmpty(originName)){
            return CommonResult.error(BAD_REQUEST);
        }
        String fileType=originName.substring(originName.lastIndexOf("."));
        String fileName = originName.substring(0,originName.lastIndexOf(".")) + "-" +  DateUtils.getUserDate("yyyyMMddhhmmss")+ RandomUtils.nextInt(1,9999) + fileType;
        return success(fileApi.createFile(fileName, IoUtil.readBytes(file.getInputStream())));
    }

    @PostMapping("/getOccupationGenerateSignature")
    @ApiOperation("获取就业星加密串")
    public CommonResult<Map<String,String>> getOccupationGenerateSignature(@RequestBody WebStudentBaseVO studentBaseVO) throws Exception {
        String mobile = studentBaseVO.getMobile();
        String studentName = studentBaseVO.getStudentName();
        if(StringUtils.isBlank(studentName) ||
                StringUtils.isBlank(mobile)){
            return error("学生姓名和手机号不能为空");
        }
        Map<String,String> result=new HashMap<>();
        String signature= Md5Util.generateSignature(secretId,secretKey,mobile,studentName);
        SignatureRespVO signatureRespVO=new SignatureRespVO();
        signatureRespVO.setSecretId(secretId);
        signatureRespVO.setSignature(signature);
        signatureRespVO.setStudentNumber(mobile);
        signatureRespVO.setStudentName(studentName);
        signatureRespVO.setSchoolName(Md5Util.COMMON_NAME);
        signatureRespVO.setMajorName(Md5Util.COMMON_NAME);
        signatureRespVO.setClassName(Md5Util.COMMON_NAME);
        String json = JsonUtils.toJsonString(signatureRespVO);
        String encode = URLEncoder.encode(Base64.getEncoder().encodeToString(json.getBytes(StandardCharsets.UTF_8)),"UTF-8");
        result.put("secretId",secretId);
        result.put("fromValue",encode);
        return success(result);
    }

    @PostMapping("/getWechatPhone")
    @ApiOperation("获取微信手机号")
    public CommonResult<String> getWechatPhone(@Valid @RequestBody WechartTokenReqVo createReqVO) {
       return success(webStudentService.getWechatPhone(createReqVO));
    }

    @PutMapping("/changeStudentPhone")
    @ApiOperation("更新学生手机")
    public CommonResult<Boolean> changeStudentPhone(@RequestBody WebStudentUpdatePhoneReqVO updateReqVO) {
        webStudentService.changeStudentPhone(updateReqVO);
        return success(true);
    }


    @GetMapping("/getOssInfo")
    @ApiOperation("获得OSS配置")
    @TenantIgnore
    public CommonResult<String> getOssInfo() throws Exception {
        String ossInfo = fileApi.getOssInfo();
        if(StringUtils.isNotBlank(ossInfo)){
            Gson gson = new GsonBuilder().serializeNulls().disableHtmlEscaping().create();
            S3FileClientConfigVO fileClientConfig = gson.fromJson(ossInfo, S3FileClientConfigVO.class);
            String json = JsonUtils.toJsonString(fileClientConfig);
            String encrypt = EncryptionUtils.encrypt(json);
            log.info("encrypt====="+encrypt);
            return success(encrypt);
        }
        return success();
    }
}
